/* 
 * File:   ScreenManager.cpp
 * Author: paula
 * 
 * Created on 12 de octubre de 2014, 11:47
 */

#include "ScreenManager.h"

ScreenManager::ScreenManager() {
}

ScreenManager::ScreenManager(float mapWidth, float mapHeight, float windowWidth, float windowHeight, int player) {
    this->settings = new SDL_Rect();
    this->mapHeight = mapHeight;
    this->mapWidth = mapWidth;
    this->screenWidth = windowWidth;
    this->screenHeight = windowHeight;
    this->borderX = this->screenWidth * BORDER;
    this->borderY = this->screenHeight * BORDER;
    this->settings->x = 0;
    this->settings->y = 0;
    this->settings->w = 0;
    this->settings->h = 0;
    this->character = player;
    this->deltaMapY = 20;
    this->deltaMapX = 6.4;
    this->posAntMapX = 0;
    this->posAntMapY = 0;
    this->characterMapPosY = 0;
    this->characterMapPosX = 0;
    this->deltaZoom = 0.05;
    this->minZoom = 1.0;
    this->initialZoom = 0.30;
    this->maxZoom = this->screenHeight / 400; //denominador mayor a 240. Ideal: 400
    this->zoom = this->initialZoom;
    this->observer = false;

}

ScreenManager::ScreenManager(const ScreenManager& orig) {
}

void ScreenManager::setZoom(float zoomIn, float zoomOut) {
    if (!this->observer) {
        if (zoomIn) {
            this->zoom = this->zoom + this->deltaZoom;
            if (this->zoom > this->maxZoom) {
                this->zoom = this->maxZoom;
            }
        }
        if (zoomOut) {
            this->zoom = this->zoom - this->deltaZoom;
            if (this->zoom < this->initialZoom) {
                this->zoom = this->initialZoom;
            }
        }

        float oldW = settings->w;
        float oldH = settings->h;

        if (this->mapWidth <= this->mapHeight) {
            settings->w = this->screenWidth / zoom;
            settings->h = (settings->w * this->screenHeight) / this->screenWidth;
        } else {
            settings->h = this->screenHeight / zoom;
            settings->w = (settings->h * this->screenWidth) / this->screenHeight;
        }

        float deltaLeft = this->characterScreenPosX;
        float deltaRight = this->screenWidth - (this->characterScreenPosX + ((PRINCIPAL_BODY_WIDTH * PRINCIPAL_SCALE * zoom)));
        float deltaUp = this->characterScreenPosY;
        float deltaDown = this->screenHeight - (this->characterScreenPosY + ((PRINCIPAL_BODY_HEIGHT * PRINCIPAL_SCALE * zoom)));

        float marginW = oldW - this->settings->w;
        float marginH = oldH - this->settings->h;
        float diffW = deltaLeft - deltaRight;
        float diffH = deltaUp - deltaDown;
        int delta = 50 * zoom;
        if ((diffW < delta) && (diffW > -delta)) {
            settings->x = settings->x + (marginW / 2);
        } else {
            if (zoomIn) {
                if (diffW > 0) {
                    settings->x = settings->x + marginW;
                }
            } else {
                if (diffW < 0) {
                    settings->x = settings->x + marginW;
                }
            }
        }
        if ((diffH < delta) && (diffH > -delta)) {
            settings->y = settings->y + (marginH / 2);
        } else {
            if (zoomIn) {
                if (diffH > 0) {
                    settings->y = settings->y + marginH;
                }
            } else {
                if (diffH < 0) {
                    settings->y = settings->y + marginH;
                }
            }
        }
        if (settings->x < 0) {
            settings->x = 0;
        }
        if (settings->y < 0) {
            settings->y = 0;
        }
        if ((settings->x + settings->w) > mapWidth) {
            settings->x = mapWidth - settings->w;
        }
        if ((settings->y + settings->h) > mapHeight) {
            settings->y = mapHeight - settings->h;
        }
    } else {
        this->zoom = this->minZoom;
    }
}

void ScreenManager::actualizeSettings() {

    this->setCharacterScreenPos();

    if ((characterScreenPosX >= (this->screenWidth - borderX - (PRINCIPAL_BODY_WIDTH * PRINCIPAL_SCALE * zoom))) && ((mapWidth - settings->x - settings->w) > 0)) {
        float plusDeltaX = (characterScreenPosX - (this->screenWidth - borderX - (PRINCIPAL_BODY_WIDTH * PRINCIPAL_SCALE * zoom)));
        settings->x = settings->x + plusDeltaX;
    }
    if ((characterScreenPosX <= borderX) && (settings->x > 0)) {
        settings->x = settings->x + (characterScreenPosX - borderX);
    }
    if (characterScreenPosY >= (this->screenHeight - borderY - (PRINCIPAL_BODY_HEIGHT * PRINCIPAL_SCALE * zoom)) && ((mapHeight - settings->y - settings->h) > 0)) {
        float plusDeltaY = (characterScreenPosY - (this->screenHeight - borderY - (PRINCIPAL_BODY_HEIGHT * PRINCIPAL_SCALE * zoom)));
        settings->y = settings->y + plusDeltaY;
    }
    if ((characterScreenPosY <= borderY)&& (settings->y > 0)) {
        settings->y = settings->y + (characterScreenPosY - borderY);
    }
}

void ScreenManager::setCharacterPos(float x, float y) {
    if (!this->observer) {
        if ((x < this->mapWidth) && (y < this->mapHeight)) {
            this->posAntMapX = this->characterMapPosX;
            this->posAntMapY = this->characterMapPosY;
            this->characterMapPosX = (x)-(PRINCIPAL_BODY_WIDTH * PRINCIPAL_SCALE / 2);
            this->characterMapPosY = (y)-(PRINCIPAL_BODY_HEIGHT * PRINCIPAL_SCALE / 2);

            if ((characterMapPosX != 0) && (characterMapPosY != 0)) {
                this->deltaMapX = this->posAntMapX - this->characterMapPosX;
                this->deltaMapY = this->posAntMapY - this->characterMapPosY;
            }
        }
    }
}

void ScreenManager::setCharacterScreenPos() {
    characterScreenPosX = (characterMapPosX - settings->x) * zoom;
    characterScreenPosY = (characterMapPosY - settings->y) * zoom;

}

int ScreenManager::getCharacterId() {
    return this->character;
}

void ScreenManager::draw(SDL_Renderer** gRenderer, SDL_Texture** mTexture) {
    SDL_RenderCopy(*gRenderer, *mTexture, settings, NULL);
}

void ScreenManager::setPosCamera(float x, float y) {
    settings->x = x;
    settings->y = y;
}

void ScreenManager::setObserver() {
    this->observer = true;
//    this->characterMapPosX = this->posAntMapX;
//    this->characterMapPosY = this->posAntMapY;
//    this->characterMapPosX = 1000;
//    this->characterMapPosY = 1000;
}

ScreenManager::~ScreenManager() {
    delete settings;
}

